#include "detectiontab.h"
#include "ui_detectiontab.h"

DetectionTab::DetectionTab(QWidget *parent) :
    QWidget(parent),
    m_ui(new Ui::DetectionTab),pOpener(new ProjectOpener),
    imgL(new ImageLoader)
{
    m_ui->setupUi(this);
}

DetectionTab::~DetectionTab()
{
    delete m_ui;
    if(pOpener) delete pOpener;
}

void DetectionTab::changeEvent(QEvent *e)
{
    QWidget::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        m_ui->retranslateUi(this);
        break;
    default:
        break;
    }
}
/*
 *  Open a project file called'fileName'
 *
 */
void DetectionTab::populate(const QString &fileName)
{
    if(pOpener)
        pOpener->addFile(fileName);
    else return;

    QStringList families = pOpener->getFamily();
    // Get all image files from the projectOpener
    QVector<QString>  files = pOpener->getFiles();

    if(files.size() > 0)
    {
        imgL->addFiles(files);

        m_ui->familyComboBox->clear();
        m_ui->familyComboBox->addItem("----------");
        m_ui->familyComboBox->addItems(families);
        connect(m_ui->familyComboBox, SIGNAL(activated(QString)),
                this, SLOT(updatePDN(QString)));

        m_ui->start_label->setText(pOpener->getStartTime());
        m_ui->info_text->setText(pOpener->getProjInfo());

        reload();
    }
    else
    {
        QMessageBox msgBox;
        msgBox.setText("No image files can be opened!");
        msgBox.exec();
    }
}

void DetectionTab::updatePDN(QString family)
{
    if(family != tr("----------") && family.length() > 0)
    {
        QStringList pdnList = pOpener->getPDN(family);
        m_ui->pdnComboBox->clear();
        m_ui->pdnComboBox->addItem("----------");
        m_ui->pdnComboBox->addItems(pdnList);
        updateChild(pdnList, 1);
        connect(m_ui->pdnComboBox, SIGNAL(activated(QString)),
                this, SLOT(updateTime(QString)));
    }
}

void DetectionTab::updateTime(QString pdn)
{


    QString family = m_ui->familyComboBox->currentText();
    if(family != tr("----------") && family.length() > 0 && pdn != tr("----------") && pdn.length() > 0)
    {
        QStringList timeList = pOpener->getTime(family, pdn);

        m_ui->timeComboBox->clear();
        m_ui->timeComboBox->addItem("----------");
        m_ui->timeComboBox->addItems(timeList);

        connect(m_ui->timeComboBox, SIGNAL(activated(QString)), this, SLOT(updateByTime(QString)));
    }
}

void DetectionTab::updateByTime(QString time)
{
    if(time.length() > 0 && time != tr("----------"))
    {

    }
}

// Calculate and display histogram for current displayed image
void DetectionTab::drawHistogram()
{
    curr = imgL->getCurrFile();
    Mat img = imread(curr.toStdString());

    if(!img.data) return;

    Mat hsv, rgb, histImg;

    cvtColor(img, hsv, CV_BGR2HSV);

    int width = m_ui->histLabel->width();
    int height = m_ui->histLabel->height();
    double maxVal = 0;
    int max_pos;

    int hbins=20, vbins=12;
    int histSize[] = {hbins, vbins};
    float hranges[] = {0, 180};
    float vranges[] = {0, 255};
    const float* ranges[] = {hranges, vranges};

    MatND hist;
    // compute the histogram from 1-st and 2-nd channels
    int channels[] = {0, 2};

    calcHist(&hsv, 1, channels, Mat(), hist, 2, histSize, ranges, true, false);
    normalize(hist, hist, 0, hbins*vbins*100, NORM_MINMAX, -1, Mat());
    minMaxLoc(hist, 0, &maxVal, 0, &max_pos);

    m_ui->maxLabel->setText(QString::number(maxVal));
    m_ui->maxlocLabel->setText(QString::number(max_pos));

    histImg = Mat::zeros(height, width, img.type());

    Mat hsv_c = Mat(1, 1, CV_8UC3);
    Mat rgb_c = Mat(1, 1, CV_8UC3);

    IplImage hsv_i = hsv_c;
    IplImage rgb_i = rgb_c;

    for(int x=0; x<hbins; x++)
    {
        for(int y=0; y<vbins; y++)
        {
            int ind = x*vbins + y;
            float bin_val = hist.at<float>(x, y);
            int va = cvRound(bin_val*height/maxVal);
            cvSet2D(&hsv_i, 0, 0, cvScalar(x*180.f/hbins, y*255.f/vbins, 255, 0));
            cvtColor(hsv_c, rgb_c, CV_HSV2BGR);
            CvScalar color = cvGet2D(&rgb_i, 0, 0);
            rectangle(histImg, Point(ind*4, height),
                      Point(ind*4+3, height-va),
                      color, -1);
            }
    }

    cvtColor(histImg, rgb, CV_BGR2RGB);

    uchar *data = rgb.data;
    int bytes = rgb.step;

    QImage qTemp = QImage(data, width, height, bytes, QImage::Format_RGB888);
    m_ui->histLabel->setPixmap(QPixmap::fromImage(qTemp, 0));
}

// Save current result image to 'file' provided by
// user
bool DetectionTab::saveImage(const QString &file)
{
    Mat img = imgL->getResultImage();
    if(img.data)
    {
        return imwrite(file.toStdString(), img);
    }

    return false;
}

void DetectionTab::updateChild(const QStringList& filter, int type)
{
    // When type==1, update icons based on pdn numbers
    // which all belong to single family/genotype
    if(type == 1)
    {
        imgL->updateIcons(filter);
    }
    else if(type == 2)
    {

    }
    reload();
}

// Get current image in the display image box.
QString DetectionTab::getCurrImg()
{    
    if(imgL) curr = imgL->getCurrFile();
    return curr;
}

void DetectionTab::showContent()
{
    if(imgL != 0)
        m_ui->mainGridLayout->addWidget(imgL, 0, 0);
}

void DetectionTab::reload()
{
    imgL->reload();
}

QVector<QString> DetectionTab::getFiles()
{
    return imgL->getFiles();
}

bool DetectionTab::isProjOpened()
{
    if(pOpener == 0) return false;

    // Both a project has been opened and image files have
    // been successfully loaded
    if(pOpener->isProjOpened() && imgL->getLoadedSize() > 0)
        return true;

    return false;
}
